home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.2 Applications 1996 May / SGI IRIX 6.2 Applications 1996 May.iso / dist / impr_dev.idb / usr / impressario / src / drivers / laserjetPJL / pclpjl.c.z / pclpjl.c
C/C++ Source or Header  |  1996-05-06  |  25KB  |  898 lines

  1. /**************************************************************************
  2.  *
  3.  *           Copyright (c)    1992 Silicon Graphics, Inc.
  4.  *            All Rights Reserved
  5.  *
  6.  *       THIS    IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SGI
  7.  *
  8.  * The copyright notice above does not evidence any actual of intended
  9.  * publication of such source code, and is an unpublished work by Silicon
  10.  * Graphics, Inc. This material contains CONFIDENTIAL INFORMATION that is
  11.  * the property of Silicon Graphics, Inc. Any use, duplication or
  12.  * disclosure not specifically authorized by Silicon Graphics is strictly
  13.  * prohibited.
  14.  *
  15.  * RESTRICTED RIGHTS LEGEND:
  16.  *
  17.  * Use, duplication or disclosure by the Government is subject to
  18.  * restrictions as set forth in subdivision (c)(1)(ii) of the Rights in
  19.  * Technical Data and Computer Software clause at DFARS 52.227-7013,
  20.  * and/or in similar or successor clauses in the FAR, DOD or NASA FAR
  21.  * Supplement. Unpublished - rights reserved under the Copyright Laws of
  22.  * the United States. Contractor is SILICON GRAPHICS, INC., 2011 N.
  23.  * Shoreline Blvd., Mountain View, CA 94039-7311
  24.  **************************************************************************
  25.  *
  26.  * File: pclpjl.c
  27.  *
  28.  * Summary:
  29.  *    PCL/PJL utility library.  Contains routines to generate common
  30.  *    PCL amd PJL commands.
  31.  *
  32.  * Description and guidelines:
  33.  *
  34.  *    Set of routines that know how to drive HP PCL printers.  Written for
  35.  *    the HP laserjet models 4Plus and newer.  
  36.  *
  37.  *    PCL functions start with 'pcl'.  PJL functions start with 'pjl'
  38.  *    PJL functions called after PCL functions (typically).
  39.  *    Not designed as a set of isolation routines -- caller needs to
  40.  *    call in correct order and should understand the internals before
  41.  *    using.  
  42.  *
  43.  *    All functions return LJ_EXIT_OK if no error; else an error code from 
  44.  *    pclpjl.h is returned;
  45.  *
  46.  *    ferror should be used by the caller if the returned error is
  47.  *    LJ_WRITE_STREAM_ERR.
  48.  *
  49.  *    Routines that do not start with 'pcl' or 'pjl' should not be 
  50.  *    used outside of this file.
  51.  *
  52.  * See Also:
  53.  *    Hp's PCL and PJL manuals
  54.  * 
  55.  **************************************************************************/
  56.     
  57. #ident "$Revision: 1.5 $"
  58.  
  59. #include <stdlib.h>
  60. #include <unistd.h>
  61. #include <stdio.h>
  62. #include <bstring.h>
  63. #include <math.h>
  64. #include "laserjetPJL.h"
  65. #include "pclpjl.h"
  66.  
  67. /* Header string for each line to send to printer */
  68.  
  69. #define HEADER_LEN 40
  70.  
  71. /* Model number in use.  Should be set by caller with escSetModel before
  72.  * calling other functions.  Allows some functions to be slightly different
  73.  * if a particular model requries it.
  74.  */
  75.  
  76. static int Model = LJ_MODEL_DEFAULT;
  77.  
  78. /* Tells us if we have set the compression mode */
  79.  
  80. static int CompressionSet = -1;
  81.  
  82. /* Once in ratser mode we set InRasterMode so we can get out if job aborted. */
  83.  
  84. static boolean InRasterMode = FALSE;
  85.  
  86. static boolean NoPJL = FALSE;
  87.  
  88. static boolean Debug = FALSE;
  89.  
  90. static int HorizResolution = DEFAULT_RESOLUTION;  
  91. static int VertResolution  = DEFAULT_RESOLUTION;  
  92.  
  93. /**************************************************************************/
  94.  
  95. int pjlsetNoPJL(boolean noPJL)
  96. {
  97.    NoPJL = noPJL;
  98.    return (LJ_EXIT_OK); 
  99.     
  100. }
  101.  
  102. /**************************************************************************/
  103.  
  104. int pjlSetModel(char *modelName) 
  105. {
  106.  
  107.    /* Call first, used by all routines if they need to do something
  108.     * device specific.  Compares modelName to known model names in the
  109.     * pclpjl.h file.
  110.     */
  111.  
  112.    int ii;
  113.  
  114.    Model = LJ_MODEL_DEFAULT;
  115.    for (ii=0; ii<LJ_NUM_MODELS; ii++) {
  116.       if (!(strcasecmp(modelName,LJ_MODEL_NAMES[ii]))) {
  117.          Model = ii; 
  118.          break;
  119.       }
  120.    }
  121.  
  122.    if (Debug) {
  123.       fprintf(stderr,"pjlSetModel: model=%s\n",modelName);
  124.       fprintf(stderr,"pjlSetModel: Model=%i\n",Model);
  125.    }
  126.  
  127.    return (LJ_EXIT_OK); 
  128. }
  129.  
  130. /**************************************************************************/
  131.  
  132. int pjlGetModel() 
  133.    /* Supply model to caller in case caller does something device specific */
  134.  
  135.    if (Debug) fprintf(stderr,"pjlGetModel called.  Model=%i\n",Model);
  136.  
  137.    return(Model);
  138. }
  139.  
  140. /**************************************************************************/
  141.  
  142. int pjlEnterPJLMode(FILE *out)
  143. {
  144.    /* Enter PJL mode by sending UEL */
  145.  
  146.    if (Debug) fprintf(stderr,"pjlEnterPJLMode called\n");
  147.  
  148.    if (NoPJL) return (LJ_EXIT_OK);
  149.  
  150.    if (fprintf(out,"\033%%-12345X@PJL\n")<0) return(LJ_WRITE_STREAM_ERR);
  151.  
  152.    if (fflush(out) != 0) return (LJ_WRITE_STREAM_ERR); 
  153.  
  154.    return (LJ_EXIT_OK);
  155. }
  156.  
  157. /**************************************************************************/
  158.  
  159. int pjlResetPrinter(FILE *out)
  160. {
  161.  
  162.    /* Normally called at end of job to reset all the printer 
  163.     * settings set with @PJL SET commands back to their front
  164.     * panel defaults.
  165.     */
  166.  
  167.    if (Debug) fprintf(stderr,"pjlResetPrinter called\n");
  168.  
  169.    if (NoPJL) return (LJ_EXIT_OK);
  170.  
  171.    if (fprintf(out,"@PJL RESET\r\n") < 0) return(LJ_WRITE_STREAM_ERR);
  172.  
  173.    if (fflush(out) != 0) return (LJ_WRITE_STREAM_ERR);
  174.  
  175.    return (LJ_EXIT_OK);
  176. }
  177.  
  178. /**************************************************************************/
  179.  
  180. int pjlEnterPCLMode(FILE *out)
  181. {
  182.    /* Enter PCL mode, anything sent after this should  be PCL  
  183.     * (but that is not enforced by these routines).  Normally an
  184.     * <esc>E is sent right after this.  See pclResetPrinter.
  185.     */
  186.  
  187.    if (Debug) fprintf(stderr,"pjlEnterPCLMode called\n");
  188.  
  189.    if (NoPJL) return (LJ_EXIT_OK);
  190.  
  191.    if (fprintf(out,"@PJL ENTER LANGUAGE=PCL\n") < 0) {
  192.       return(LJ_WRITE_STREAM_ERR);
  193.    }
  194.  
  195.    if (fflush(out) != 0) return (LJ_WRITE_STREAM_ERR); 
  196.  
  197.    return (LJ_EXIT_OK);
  198. }
  199.  
  200. /**************************************************************************/
  201.  
  202. int pjlSetCopies(FILE *out, int copies)
  203. {
  204.    /* Set number of copies.  Only check is that it is greater then 1 */
  205.     
  206.    if (Debug) fprintf(stderr,"pjlSetCopies called. copies=%i\n",copies);
  207.  
  208.    if (NoPJL) return (LJ_EXIT_OK);
  209.  
  210.    if (copies>1) {
  211.       if (fprintf(out,"@PJL SET COPIES=%i\n",copies) < 0) {
  212.          return(LJ_WRITE_STREAM_ERR);
  213.       }
  214.    }
  215.  
  216.    return (LJ_EXIT_OK);
  217. }
  218.  
  219. /**************************************************************************/
  220. int pjlSetPageProtect(FILE *out, boolean onoff)
  221. {
  222.  
  223.    /* You almost always want this turned off so the printer would not have 
  224.     * to load a full page before printing it.
  225.     */
  226.  
  227.    /*
  228.     * Model    Notes:
  229.     * 4V       Ignored (allow user to set on front panel) 
  230.     * 4P       Ignored (allow user to set on front panel) 
  231.     * 4PLUS    Ignored (allow user to set on front panel)
  232.     * 4SI      Ignored (allow user to set on front panel)
  233.     * 5L       Supports ON, OFF, AUTO (use OFF over AUTO)
  234.     * 5P       Supports ON, OFF, AUTO (use OFF over AUTO)
  235.     * 5SI      Ignored (allow user to set on front panel)
  236.    */
  237.    if  (Debug) fprintf(stderr,"pjlSetPageProtect called. onoff=%i\n",onoff);
  238.  
  239.    if (NoPJL) return (LJ_EXIT_OK);
  240.  
  241.    if ((Model ==  LJ_MODEL_5P) || (Model ==  LJ_MODEL_5L)) {
  242.       if (onoff) {
  243.          if (fprintf(out,"@PJL SET PAGEPROTECT=ON\n") < 0) {
  244.             return(LJ_WRITE_STREAM_ERR);
  245.          }
  246.       } else {
  247.          if (fprintf(out,"@PJL SET PAGEPROTECT=OFF\n") < 0) {
  248.              return(LJ_WRITE_STREAM_ERR);
  249.          }
  250.       }
  251.    }
  252.  
  253.    return (LJ_EXIT_OK);
  254. }
  255.  
  256. /**************************************************************************/
  257.  
  258. int pjlSetRes(FILE *out, int xres, int yres)
  259. {
  260.  
  261.    /* Note that setting resolution in PJL does not set the resolution for
  262.     * pcl raster graphics.  See pclSetRes.  
  263.     */
  264.  
  265.    if (Debug) {
  266.       fprintf(stderr,"pjlSetRes called. xres=%i, yres=%i\n",xres,yres);
  267.    }
  268.  
  269.    if (NoPJL) return (LJ_EXIT_OK);
  270.  
  271.    HorizResolution = xres;
  272.    VertResolution  = yres;
  273.  
  274.    if (fprintf(out,"@PJL SET RESOLUTION=%i\n",xres) < 0) {
  275.       return(LJ_WRITE_STREAM_ERR);
  276.    }
  277.  
  278.    return (LJ_EXIT_OK);
  279. }
  280.  
  281. /**************************************************************************/
  282.  
  283. int pjlSetPaperSize(FILE *out, int size)
  284. {
  285.    /* Supported paper size varies by device.  Check is not done 
  286.     * to insure device supports requested paper size.
  287.     */
  288.  
  289.    if (Debug) fprintf(stderr,"pjlSetPaperSize called. Size=%i\n",size);
  290.  
  291.    if (NoPJL) return (LJ_EXIT_OK);
  292.  
  293.    /* A 4P can jam if you tell it one paper size and another is loaded.
  294.     * So, don't set it in software -- user must set on front panel.  We
  295.     * still want user to set it on GUI so text2ps can create page breaks
  296.     * at correct location so it is still available to the user.
  297.     */
  298.  
  299.    if (Model == LJ_MODEL_4P) return (LJ_EXIT_OK);
  300.  
  301.    if (fprintf(out,"@PJL SET PAPER=") < 0) return(LJ_WRITE_STREAM_ERR);
  302.    
  303.    switch (size) {
  304.  
  305.        case -999:
  306.           if (Debug) fprintf(stderr,"pjlSetPaperSize size is CUSTOM\n");
  307.           if (fprintf(out,"CUSTOM\n") < 0) return(LJ_WRITE_STREAM_ERR);
  308.           break;
  309.  
  310.        case PD_SIZE_LEGAL:
  311.           if (Debug) fprintf(stderr,"pjlSetPaperSize size is LEGAL\n");
  312.           if (fprintf(out,"LEGAL\n") < 0) return(LJ_WRITE_STREAM_ERR);
  313.           break;
  314.  
  315.        case PD_SIZE_B:
  316.           if (Debug) fprintf(stderr,"pjlSetPaperSize size is LEDGER\n");
  317.           if (fprintf(out,"LEDGER\n") < 0) return(LJ_WRITE_STREAM_ERR);
  318.           break;
  319.  
  320.        case PD_SIZE_A4:
  321.           if (Debug) fprintf(stderr,"pjlSetPaperSize size is A4\n");
  322.           if (fprintf(out,"A4\n") < 0) return(LJ_WRITE_STREAM_ERR);
  323.           break;
  324.  
  325.        case PD_SIZE_A3:
  326.           if (Debug) fprintf(stderr,"pjlSetPaperSize size is A3\n");
  327.           if (fprintf(out,"A3\n") < 0) return(LJ_WRITE_STREAM_ERR);
  328.           break;
  329.  
  330.        case PD_SIZE_EXEC:
  331.           if (Debug) fprintf(stderr,"pjlSetPaperSize size is EXECUTIVE\n");
  332.           if (fprintf(out,"EXECUTIVE\n") < 0) return(LJ_WRITE_STREAM_ERR);
  333.           break;
  334.  
  335.        case PD_SIZE_LETTER:
  336.        default:
  337.           if (Debug) fprintf(stderr,"pjlSetPaperSize size is LETTER\n");
  338.           if (fprintf(out,"LETTER\n") < 0) return(LJ_WRITE_STREAM_ERR);
  339.           break;
  340.   }
  341.  
  342.    return (LJ_EXIT_OK);
  343. }
  344.  
  345. /**************************************************************************/
  346.  
  347. int pjlSetDuplex(FILE *out, int duplex)
  348. {
  349.    /* Only send this if the device supports duplexor.  We only send the PJL
  350.     * command if duplex is turned on.
  351.     */
  352.  
  353.    /*
  354.     * Model    Notes:
  355.     * 4V       Ignored
  356.     * 4P       Ignored
  357.     * 4PLUS    Supported (optional)
  358.     * 4SI      Supported (optional)
  359.     * 5L       Ignored
  360.     * 5P       Ignored
  361.     * 5SI      Supported (optional)
  362.    */
  363.  
  364.    if (Debug) fprintf(stderr,"pjlSetDuplexcalled.  duplex=%i\n",duplex);
  365.  
  366.    if (NoPJL) return (LJ_EXIT_OK);
  367.  
  368.    if (duplex == LJ_DUPLEX_OFF)  return (LJ_EXIT_OK);
  369.  
  370.    if (fprintf(out,"@PJL SET DUPLEX=ON\n") < 0) return(LJ_WRITE_STREAM_ERR);
  371.  
  372.    if (fprintf(out,"@PJL SET BINDING=") < 0) return(LJ_WRITE_STREAM_ERR);
  373.  
  374.    if (duplex == LJ_DUPLEX_SHORTSIDE) {
  375.       if (fprintf(out,"SHORTEDGE\n") < 0) return(LJ_WRITE_STREAM_ERR);
  376.    } else {
  377.       if (fprintf(out,"LONGEDGE\n") < 0) return(LJ_WRITE_STREAM_ERR);
  378.    }
  379.  
  380.    return (LJ_EXIT_OK);
  381. }
  382.  
  383. /**************************************************************************/
  384.  
  385. int pjlSetOutBin(FILE *out, int bin)
  386. {
  387.    if (Debug) fprintf(stderr,"pjlSetOutBin called. bin=%i\n",bin);
  388.    /*
  389.     * Model    Notes:
  390.     * 5SI      This is only model supported
  391.     */
  392.  
  393.     if (NoPJL) return (LJ_EXIT_OK);
  394.  
  395.     if (Model != LJ_MODEL_5SI) return (LJ_EXIT_OK);
  396.  
  397.     if (bin == LJ_OUTBIN_TOP) {
  398.        if (fprintf(out,"@PJL SET OUTBIN=UPPER\n") < 0)  {
  399.           return(LJ_WRITE_STREAM_ERR);
  400.        }
  401.     } else if (bin == LJ_OUTBIN_REAR ) {
  402.        if (fprintf(out,"@PJL SET OUTBIN=LOWER\n") < 0)  {
  403.           return(LJ_WRITE_STREAM_ERR);
  404.        }
  405.     }
  406.  
  407.     return (LJ_EXIT_OK);
  408.  
  409. }
  410.  
  411.  
  412. /**************************************************************************/
  413.  
  414. int pjlSetTray(FILE *out, int tray)
  415. {
  416.    /* Some printers set tray based on paper type; others can not. 
  417.     * This is also used to put printer into manual mode.
  418.     */
  419.  
  420.    /*
  421.     * Model    Notes:
  422.     * 4V       Only MANUAL supported, let paper size dictate tray selection
  423.     * 4P       Only MANUAL supported
  424.     * 4PLUS    Only MANUAL supported (use PCL for other trays)
  425.     * 4SI      Only MANUAL  (use PCL for other trays)
  426.     * 5L       Only MANUAL supported (no optional trays available)
  427.     * 5P       Allows MP to be set as CASSETTE, FIRST, or MANUAL
  428.     * 5SI      Only MANUAL, let paper size and media type dictate tray used
  429.     */
  430.  
  431.    if (Debug) fprintf(stderr,"pjlSetTray called. tray=%i\n",tray);
  432.  
  433.    if (NoPJL) return (LJ_EXIT_OK);
  434.  
  435.    if (tray == LJ_TRAY_MANUAL) {
  436.       if (fprintf(out,"@PJL SET MANUALFEED=ON\n") < 0) {
  437.          return(LJ_WRITE_STREAM_ERR);
  438.       }
  439.       if (Model ==  LJ_MODEL_5P) {
  440.          if (fprintf(out,"@PJL SET MPTRAY=MANUAL\n") < 0) {
  441.             return(LJ_WRITE_STREAM_ERR);
  442.          }
  443.       }
  444.       
  445.    }  else if (Model ==  LJ_MODEL_5P) {
  446.  
  447.       if (Debug) fprintf(stderr,"pjlSetTray called model is 5P\n");
  448.  
  449.       if (tray == LJ_TRAY_UPPER) {  /* Paper Cassette / Tray 2 */
  450.          if (fprintf(out,"@PJL SET MPTRAY=CASSETTE\n") < 0) {
  451.             return(LJ_WRITE_STREAM_ERR);
  452.          }
  453.       } else if (tray ==  LJ_TRAY_LOWER) { /* MP tray / Tray 1 */
  454.          if (fprintf(out,"@PJL SET MPTRAY=CASSETTE\n") < 0) {
  455.             return(LJ_WRITE_STREAM_ERR);
  456.          }
  457.       } else if (tray ==  LJ_TRAY_EITHER) {
  458.          if (fprintf(out,"@PJL SET MPTRAY=FIRST\n") < 0) {
  459.             return(LJ_WRITE_STREAM_ERR);
  460.          }
  461.       }
  462.  
  463.    } 
  464.  
  465.    return (LJ_EXIT_OK);
  466. }
  467.  
  468. /**************************************************************************/
  469.  
  470. int pjlSetDarkness(FILE *out, int darkness)
  471. {
  472.    int density=3;
  473.  
  474.    /* Valid density is 1 to 5; we support normal, dark and light.
  475.     * an Economode setting is also supported.
  476.     */
  477.  
  478.    /*
  479.     * Model    Notes:
  480.     * 4V       Only ECONOMODE set; (set density on front panel)
  481.     * 4P       ECONOMODE and DENSITY supported
  482.     * 4PLUS    Only ECONOMODE set; (set density on front panel)
  483.     * 4SI      Not supported
  484.     * 5L       ECONOMODE and DENSITY supported 
  485.     * 5P       ECONOMODE and DENSITY supported
  486.     * 5SI      Only ECONOMODE set; (set density on front panel)
  487.    */
  488.  
  489.    if (Debug) fprintf(stderr,"pjlSetDarkness called darkness=%i\n",darkness);
  490.  
  491.    if (NoPJL)  return (LJ_EXIT_OK);
  492.  
  493.    if (Model == LJ_MODEL_4SI) return (LJ_EXIT_OK);
  494.  
  495.    if (darkness == LJ_DARKNESS_ECONO) {
  496.  
  497.       if (fprintf(out,"@PJL SET ECONOMODE=ON\n") < 0) {
  498.          return(LJ_WRITE_STREAM_ERR);
  499.       }
  500.       density = 3;
  501.  
  502.    } else if (darkness == LJ_DARKNESS_LIGHT) {
  503.       density = 1;
  504.    } else if (darkness == LJ_DARKNESS_DARK) {
  505.       density = 5;
  506.    } else if (darkness == LJ_DARKNESS_NORMAL) {
  507.       density = 3;
  508.    }
  509.  
  510.    if ((Model ==  LJ_MODEL_5P) || (Model ==  LJ_MODEL_4P)) {
  511.       if (Debug) fprintf(stderr,"pjlSetDarkness default density=%i\n",density);
  512.       if (fprintf(out,"@PJL DEFAULT DENSITY=%i\n",density) < 0) {
  513.          return(LJ_WRITE_STREAM_ERR);
  514.       }
  515.    } else if (Model ==  LJ_MODEL_5L) {
  516.       if (Debug) fprintf(stderr,"pjlSetDarkness set density=%i\n",density);
  517.       if (fprintf(out,"@PJL SET DENSITY=%i\n",density) < 0) {
  518.          return(LJ_WRITE_STREAM_ERR);
  519.       }
  520.    }
  521.    
  522.    return (LJ_EXIT_OK);
  523. }
  524.  
  525. /**************************************************************************/
  526.  
  527. void pjlSetDebug(boolean onoff) 
  528. {
  529.  
  530.     /* Turn on debug nessages in the PJL and PCL functions in this file */
  531.  
  532.     Debug = onoff;
  533.  
  534. /**************************************************************************/
  535.  
  536. int pclSetRes(FILE *out, int xres, int yres)
  537. {
  538.  
  539.    /* Set PCL raster graphics resolution.  Settings from PJL are ignored
  540.     * so make sure you also set resolution in pcl.  yres is ignored.
  541.     */
  542.  
  543.    if (Debug) {
  544.       fprintf(stderr,"pclSetRes called. xres=%i, yres=%i\n",xres,yres);
  545.    }
  546.  
  547.    if (fprintf(out, "\033*t%dR", xres)  < 0) return(LJ_WRITE_STREAM_ERR);
  548.  
  549.    return (LJ_EXIT_OK);
  550. }
  551.  
  552. /**************************************************************************/
  553.  
  554. int pclSetLineWrap(FILE *out)
  555. {
  556.    /* Enable the end of line wrap in pcl */
  557.  
  558.    if (Debug) fprintf(stderr,"pclSetLineWrap  called\n");
  559.  
  560.    if (fprintf(out,"\033&s0C") < 0) return(LJ_WRITE_STREAM_ERR);
  561.  
  562.    return (LJ_EXIT_OK);
  563. }
  564.  
  565. /**************************************************************************/
  566.  
  567. int pclSetCrLf(FILE *out)
  568. {
  569.    /* Set CR/LF model to CR=CR; LF=CR-LF; FF=CR-FF*/
  570.  
  571.    if (Debug) fprintf(stderr,"pclSetCrLf called\n");
  572.  
  573.    if (fprintf(out,"\033&k2G") < 0) return(LJ_WRITE_STREAM_ERR);
  574.  
  575.    return (LJ_EXIT_OK);
  576. }
  577.  
  578. /**************************************************************************/
  579.  
  580. int pclFormFeed(FILE *out)
  581. {
  582.    /* Send a form feed */
  583.  
  584.    if (Debug) fprintf(stderr,"pclFormFeed called\n");
  585.  
  586.    if (fprintf(out,"\014") < 0) return(LJ_WRITE_STREAM_ERR);
  587.  
  588.    if (fflush(out) != 0) return (LJ_WRITE_STREAM_ERR);
  589.  
  590.    return (LJ_EXIT_OK);
  591. }
  592.  
  593. /**************************************************************************/
  594.  
  595. int pclResetPrinter(FILE *out)
  596. {
  597.    /* Send a PCL reset */
  598.  
  599.    if (Debug) fprintf(stderr,"pclResetPrinter called\n");
  600.  
  601.    if (fprintf(out,"\033E") < 0) return(LJ_WRITE_STREAM_ERR);
  602.  
  603.    return (LJ_EXIT_OK);
  604. }
  605.  
  606.  
  607. /**************************************************************************/
  608.  
  609. int pclSetTray(FILE *out, int tray)
  610. {
  611.  
  612.    /*
  613.     * Model    Notes:
  614.     * 4V       MANUAL and 2 trays (1 optional) supported
  615.     * 4PLUS    MANUAL and 2 trays (1 optional) supported 
  616.     * 4SI      2 Trays (standard with printer) supported
  617.     * 4P       Only MANUAL supported (no optional trays available)
  618.     * 5L       Only MANUAL supported (no optional trays available)
  619.     * 5P       Allows selection between MP tray and paper drawer
  620.     * 5SI      Not supported (paper size and type selects tray on 5SI) 
  621.    */
  622.  
  623.    if (Debug) fprintf(stderr,"pclSetTray called. tray=%i\n",tray);
  624.  
  625.    if (tray == LJ_TRAY_MANUAL) {
  626.  
  627.       if (fprintf(out,"\033&l2H") < 0) {
  628.          return(LJ_WRITE_STREAM_ERR);
  629.       }
  630.  
  631.    } else if ((Model ==  LJ_MODEL_5P) || (Model ==  LJ_MODEL_4SI) ||
  632.               (Model ==  LJ_MODEL_5SI))  {
  633.  
  634.       if (Debug) fprintf(stderr,"pclSetTray called model is 5P/4SI/4V\n");
  635.  
  636.       if (tray == LJ_TRAY_UPPER) {  /* Paper Cassette / upper / Tray 2 */
  637.          if (fprintf(out,"\033&l1H") < 0) {
  638.             return(LJ_WRITE_STREAM_ERR);
  639.          }
  640.       } else if (tray ==  LJ_TRAY_LOWER) { /* MP tray / lower/ Tray 1 */
  641.          if (fprintf(out,"\033&l4H") < 0) {
  642.             return(LJ_WRITE_STREAM_ERR);
  643.          }
  644.       }
  645.   
  646.    }  else if ((Model == LJ_MODEL_4PLUS) || (Model == LJ_MODEL_4V))  {   
  647.  
  648.       if (tray == LJ_TRAY_UPPER) {  
  649.          if (fprintf(out,"\033&l1H") < 0) {
  650.             return(LJ_WRITE_STREAM_ERR);
  651.          }
  652.       } else if (tray ==  LJ_TRAY_LOWER) { 
  653.          if (fprintf(out,"\033&l5H") < 0) {
  654.             return(LJ_WRITE_STREAM_ERR);
  655.          }
  656.       }
  657.  
  658.    }
  659.  
  660.    return (LJ_EXIT_OK);
  661. }
  662.  
  663. /**************************************************************************/
  664.  
  665. int pclPrepForGraphics(FILE *out)
  666. {
  667.    /* Get ready for graphics mode. Calls several pcl functions.
  668.     * Specific to the laserjet driver dor Impressario in that some
  669.     * values are hard-coded.
  670.     */
  671.  
  672.    if (Debug) fprintf(stderr,"pclPrepForGraphics called\n");
  673.  
  674.    /* Enter new page so mark compression used as unknown for pclSendRow */
  675.  
  676.    CompressionSet = -1;
  677.  
  678.    /* Set portrait mode on & zero top margin */
  679.  
  680.    if (fprintf(out, "\033&l0ol0E") < 0) return(LJ_WRITE_STREAM_ERR);
  681.  
  682.    /* Set zero left margin */
  683.  
  684.    if (fprintf(out, "\033&l0L") < 0) return(LJ_WRITE_STREAM_ERR);
  685.  
  686.    /* Move graphics cursor to 0,50 */
  687.  
  688.    if (fprintf(out, "\033*p0x50Y") < 0) return(LJ_WRITE_STREAM_ERR);
  689.  
  690.    /* Start raster graphics mode. */
  691.  
  692.    if (fprintf(out, "\033*r1A") < 0) return(LJ_WRITE_STREAM_ERR);
  693.    InRasterMode = TRUE;
  694.  
  695.    if (fflush(out) != 0) return (LJ_WRITE_STREAM_ERR);
  696.  
  697.    return (LJ_EXIT_OK);
  698. }
  699.  
  700. /**************************************************************************/
  701.  
  702. int pclPrepForNextPage(FILE *out)
  703. {
  704.    if (Debug) fprintf(stderr,"pclPrepForNextPage called\n");
  705.  
  706.    /* Get ready for next page */
  707.  
  708.    /* End raster graphics */
  709.  
  710.    if (InRasterMode) {
  711.      if (fprintf(out, "\033*rC") < 0) return(LJ_WRITE_STREAM_ERR);
  712.      InRasterMode = FALSE;
  713.    }
  714.  
  715.    if (pclFormFeed(out) != LJ_EXIT_OK) return(LJ_WRITE_STREAM_ERR);
  716.  
  717.    return (LJ_EXIT_OK);
  718. }
  719.  
  720. /**************************************************************************/
  721.  
  722. int pclFlushPages(FILE *out)
  723. {
  724.    if (Debug) fprintf(stderr,"pclFlushPages called\n");
  725.  
  726.    if (fprintf(out, "\033&r1F") < 0) return(LJ_WRITE_STREAM_ERR);
  727.  
  728.    if (fflush(out) != 0) return (LJ_WRITE_STREAM_ERR);
  729.  
  730.    return (LJ_EXIT_OK);
  731. }
  732.  
  733. /**************************************************************************/
  734.  
  735. int pclCleanupPrinter(FILE *out)
  736. {
  737.    if (Debug) fprintf(stderr,"pclCleanupPrinter called\n");
  738.  
  739.    /* End raster graphics */
  740.  
  741.    if (InRasterMode) {
  742.       if (fprintf(out, "\033*rC") < 0) return(LJ_WRITE_STREAM_ERR);
  743.       InRasterMode = FALSE;
  744.    }
  745.  
  746.    /* Send Job Separation command. */
  747.  
  748.    if (fprintf(out, "\033&l1T") < 0) return(LJ_WRITE_STREAM_ERR);
  749.  
  750.    if (pclResetPrinter(out) != LJ_EXIT_OK) return(LJ_WRITE_STREAM_ERR);
  751.  
  752.    if (fprintf(out,"\033%%-12345X") < 0) return(LJ_WRITE_STREAM_ERR);
  753.  
  754.    if (pjlEnterPJLMode(out) != LJ_EXIT_OK) return(LJ_WRITE_STREAM_ERR);
  755.  
  756.    if (pjlResetPrinter(out) != LJ_EXIT_OK) return(LJ_WRITE_STREAM_ERR);
  757.  
  758.    if (fflush(out) != 0) return (LJ_WRITE_STREAM_ERR);
  759.  
  760.     return (LJ_EXIT_OK);
  761. }
  762.  
  763.  
  764. /**************************************************************************/
  765.  
  766. int packbits(unsigned char *ibits, unsigned char *pbits, int nbytes)
  767. {
  768.     unsigned char *sptr;
  769.     unsigned char *ibitsend;
  770.     unsigned char *optr = pbits;
  771.     int todo, cc, count;
  772.  
  773.     ibitsend = ibits+nbytes;
  774.     while(ibits<ibitsend) {
  775.         sptr = ibits;
  776.         ibits += 2;
  777.         while((ibits<ibitsend)&&((ibits[-2]!=ibits[-1])||(ibits[-1]!=ibits[0])))            ibits++;
  778.         if(ibits != ibitsend) {
  779.             ibits -= 2;
  780.         }
  781.         count = ibits-sptr;
  782.         while(count) {
  783.             todo = count>128 ? 128:count;
  784.             count -= todo;
  785.             *optr++ = todo-1;
  786.             while(todo--)
  787.                 *optr++ = *sptr++;
  788.         }
  789.         if(ibits == ibitsend)
  790.             break;
  791.         sptr = ibits;
  792.         cc = *ibits++;
  793.         while( (ibits<ibitsend) && (*ibits == cc) )
  794.             ibits++;
  795.         count = ibits-sptr;
  796.         while(count) {
  797.             todo = count>128 ? 128:count;
  798.             count -= todo;
  799.             *optr++ = 257-todo;
  800.             *optr++ = cc;
  801.         }
  802.     }
  803.     return optr-pbits;
  804. }
  805.  
  806. /**************************************************************************/
  807.  
  808. int set_compression_2(FILE *out)
  809. {
  810.     if (fprintf(out,"\033*b2m")  < 0) return(LJ_WRITE_STREAM_ERR);
  811.     CompressionSet=2;
  812.     return (LJ_EXIT_OK);
  813. }
  814.  
  815. /**************************************************************************/
  816.  
  817. int set_compression_off(FILE *out)
  818. {
  819.     if (fprintf(out,"\033*b0m")  < 0) return(LJ_WRITE_STREAM_ERR);
  820.     CompressionSet=0;
  821.     return (LJ_EXIT_OK);
  822. }
  823.  
  824. /**************************************************************************/
  825.  
  826. int pclSendRow(FILE *out, unsigned char *row, unsigned long numBytes)
  827. {
  828.  
  829.     /* Send a row of raster data -- compresses and then sends */
  830.  
  831.     int bufSizeNeeded;
  832.     int bytesToWrite;
  833.     int compressLength;
  834.     int count;
  835.     int lineCount;
  836.     unsigned char *writeBuf;
  837.     unsigned char HeaderCmd[HEADER_LEN];
  838.     static int Buflength = 0;
  839.     static unsigned char *compressedRow = NULL;  
  840.  
  841.     int packbits(unsigned char *ibits, unsigned char *pbits, int nbytes);
  842.     int set_compression_off(FILE *out);
  843.     int set_compression_2(FILE *out);
  844.  
  845.     bufSizeNeeded = numBytes;
  846.  
  847.     if (Buflength < bufSizeNeeded) {  /* alloc, re-alloc as needed */
  848.        if (Buflength == 0)  {   /* first time through */
  849.           Buflength = bufSizeNeeded; 
  850.           compressedRow=(unsigned char *)malloc(Buflength*2);
  851.        } else {
  852.           Buflength = bufSizeNeeded; 
  853.           compressedRow=(unsigned char *)realloc(compressedRow,Buflength*2);
  854.        }
  855.     }
  856.  
  857.     if (!compressedRow) {
  858.        fprintf(stderr,"malloc failed while allocating bytes of memory");
  859.        exit(1);
  860.     }
  861.  
  862.     bytesToWrite = Buflength;
  863.     writeBuf = row; 
  864.  
  865.     compressLength = packbits(row, compressedRow, Buflength);
  866.     if (compressLength < Buflength) {
  867.         bytesToWrite = compressLength;
  868.         writeBuf = compressedRow;
  869.         if (CompressionSet != 2) {
  870.            if (set_compression_2(out) != LJ_EXIT_OK) {
  871.                return (LJ_WRITE_STREAM_ERR);
  872.            }
  873.         }
  874.         lineCount = sprintf(HeaderCmd,"\033*b%uW",bytesToWrite);
  875.     } else {
  876.         if (CompressionSet != 0) {
  877.            if (set_compression_off(out) != LJ_EXIT_OK) {
  878.                return (LJ_WRITE_STREAM_ERR);
  879.            }
  880.         }
  881.     }
  882.  
  883.     lineCount = sprintf(HeaderCmd,"\033*b%uW",bytesToWrite);
  884.     count = fwrite(HeaderCmd, 1, lineCount, out);
  885.     if (count != lineCount) return (LJ_WRITE_STREAM_ERR);
  886.  
  887.     count = fwrite(writeBuf, 1, bytesToWrite, out);
  888.     if (count != bytesToWrite) return (LJ_WRITE_STREAM_ERR);
  889.  
  890.     fflush(out);
  891.  
  892.     return (LJ_EXIT_OK);
  893. }
  894.  
  895. /**************************************************************************/
  896.